package com.tod.security.springsecuritydbencrypt.config;

import com.tod.security.springsecuritydbencrypt.filter.AfterCsrfFilter;
import com.tod.security.springsecuritydbencrypt.filter.AtSecurityContextPersistenceFilter;
import com.tod.security.springsecuritydbencrypt.filter.BeforeLoginFilter;
import com.tod.security.springsecuritydbencrypt.filter.PrincipalFilter;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.switchuser.SwitchUserFilter;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
import org.springframework.security.web.csrf.CsrfFilter;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Tod.xie
 * Date: 2018-02-05
 * Time: 11:28
 *
 * @author Tod.xie
 */
@EnableWebSecurity
@AllArgsConstructor
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    private final AnyUserDetailsService anyUserDetailsService;

    /**
     * 匹配 "/" 路径，不需要权限即可访问
     * 匹配 "/user" 及其以下所有路径，都需要 "USER" 权限
     * 登录地址为 "/login"，登录成功默认跳转到页面 "/user"
     * 退出登录的地址为 "/logout"，退出成功后跳转到页面 "/login"
     * 默认启用 CSRF
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/user/**").hasRole("USER")
            .antMatchers("/").permitAll()
        .and()
            .formLogin().loginPage("/login").defaultSuccessUrl("/user")
        .and()
            .logout().logoutUrl("/logout").logoutSuccessUrl("/login");

        http.addFilterBefore(beforeLoginFilter(), UsernamePasswordAuthenticationFilter.class)
            .addFilterAfter(afterCsrfFilter(), CsrfFilter.class)
            .addFilterAt(atSecurityContextPersistenceFilter(),SecurityContextPersistenceFilter.class)
            .addFilterAfter(principalFilter(), SwitchUserFilter.class);
    }

    /**
     * 添加 UserDetailsService， 实现自定义登录校验
     */
    @Override
    protected void configure(AuthenticationManagerBuilder builder) throws Exception{
        builder.userDetailsService(anyUserDetailsService).passwordEncoder(passwordEncoder());
    }

    /**
     * 密码加密
     */
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    /**
     * BeforeLoginFilter Bean
     */
    @Bean
    public BeforeLoginFilter beforeLoginFilter(){
        return new BeforeLoginFilter();
    }

    /**
     * AfterCsrfFilter Bean
     */
    @Bean
    public AfterCsrfFilter afterCsrfFilter(){
        return new AfterCsrfFilter();
    }

    /**
     * AfterCsrfFilter Bean
     */
    @Bean
    public AtSecurityContextPersistenceFilter atSecurityContextPersistenceFilter(){
        return new AtSecurityContextPersistenceFilter();
    }

    /**
     * PrincipalFilter Bean
     */
    @Bean
    public PrincipalFilter principalFilter(){
        return new PrincipalFilter();
    }
}
